package com.modelclient.baselib.util;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.widget.ImageView;

import androidx.annotation.DrawableRes;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentActivity;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.MultiTransformation;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.FutureTarget;
import com.bumptech.glide.request.RequestOptions;
import com.modelclient.baselib.R;

import java.util.concurrent.ExecutionException;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * 作者：Hxm
 * 创建时间：2017/6/8 14:04
 * 功能说明：
 */
public final class GlideUtil {
    public static RequestOptions getDefaultRequestOptions() {
        return getDefaultRequestOptions(0, false);
    }

    private static RequestOptions getDefaultRequestOptions(@DrawableRes int defaultImg, boolean circle) {
        RequestOptions options = new RequestOptions();
        options.centerCrop();
        options.diskCacheStrategy(DiskCacheStrategy.ALL);
        if (circle) {
            options.transform(new CircleCrop());
        }
        return options;
    }

    private static RequestOptions getFitCenterRequestOptions(@DrawableRes int defaultImg, boolean circle) {
        RequestOptions options = new RequestOptions();
        options.fitCenter();
        options.diskCacheStrategy(DiskCacheStrategy.ALL);
        if (circle) {
            options.transform(new CircleCrop());
        }
        return options;
    }

    @SuppressLint("CheckResult")
    private static RequestOptions roundRequestOptions() {
        RequestOptions options = new RequestOptions();
        options.placeholder(R.mipmap.defaults);
        options.diskCacheStrategy(DiskCacheStrategy.ALL);
        options.transform(new MultiTransformation<>(new CenterCrop(), new RoundedCorners(DensityUtil.dip2px(2))));
        return options;
    }

    @SuppressLint("CheckResult")
    private static RequestOptions roundRequestOptions(int mCorners) {
        RequestOptions options = new RequestOptions();
        options.transform(new MultiTransformation<>(new CenterCrop(), new RoundedCorners(DensityUtil.dip2px(mCorners))));
        return options;
    }


    @SuppressLint("CheckResult")
    private static RequestOptions squareRequestOptions() {
        RequestOptions options = new RequestOptions();
        options.placeholder(R.mipmap.defaults);
        options.diskCacheStrategy(DiskCacheStrategy.ALL);
        options.centerCrop();
        return options;
    }

    @SuppressLint("CheckResult")
    private static RequestOptions roundRequestFitOptions(int mCorners) {
        RequestOptions options = new RequestOptions();
        options.placeholder(R.mipmap.defaults);
        options.transform(new RoundedCorners(DensityUtil.dip2px(mCorners)));
        return options;
    }

    @SuppressLint("CheckResult")
    private static RequestOptions getDefaultRequestOptions(@DrawableRes int defaultImg, @DrawableRes int errorImg, int width, int height) {
        RequestOptions options = new RequestOptions();
        options.placeholder(defaultImg);
        options.error(R.mipmap.default_error);
        options.override(width, height);
        options.diskCacheStrategy(DiskCacheStrategy.ALL);
        return options;
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayImage(Context context, String url, ImageView imageView) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(getDefaultRequestOptions())
                    .into(imageView);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayImageFitCenter(Context context, String url, ImageView imageView) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(getFitCenterRequestOptions(0,false))
                    .into(imageView);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayImageFitCenter(Context context, String url, ImageView imageView
            , int placeholder, int width, int height) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(getFitCenterRequestOptions(0,false).placeholder(placeholder).error(R.mipmap.default_error).override(width,height))
                    .into(imageView);
    }


    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayImage(Context context, String url, ImageView imageView
            , int placeholder, int width, int height) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(getDefaultRequestOptions().placeholder(placeholder).error(R.mipmap.default_error).override(width,height))
                    .into(imageView);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayImage(Context context, String url, ImageView imageView
            , int placeholder, int errorholder, int width, int height) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(getDefaultRequestOptions().placeholder(placeholder).error(R.mipmap.default_error).override(width,height))
                    .into(imageView);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayImage(Context context, String url, ImageView imageView, int placeholder) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(getDefaultRequestOptions().error(R.mipmap.default_error).placeholder(placeholder))
                    .into(imageView);
    }


    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displaySquareImage(Context context, String url, ImageView imageView) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(squareRequestOptions())
                    .into(imageView);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayRoundImage(Context context, String url, ImageView imageView) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(roundRequestOptions())
                    .into(imageView);
    }


    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void showRoundImage(Context context, String url, ImageView imageView) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(roundRequestOptions())
                    .into(imageView);
    }


    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void showSquareImage(Context context, String url, ImageView imageView) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(getDefaultRequestOptions())
                    .into(imageView);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayRoundImage(Context context, String url, ImageView imageView, int mCorners) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(roundRequestOptions(mCorners))
                    .into(imageView);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayRoundFitImage(Context context, String url, ImageView imageView, int mCorners) {
        if (checkContextIllegal(context))
            Glide.with(context).load(url).apply(roundRequestFitOptions(mCorners)).into(imageView);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    private static boolean checkContextIllegal(Context context) {
        if (context != null) {
            if (context instanceof Activity) {
                if (((Activity) context).isFinishing() || ((Activity) context).isDestroyed()) {
                    return false;
                }
            }
        } else {
            return false;
        }
        return true;
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayRoundImage(Context context, String url, ImageView imageView,
                                         int mCorners, int placeholder) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(roundRequestOptions(mCorners).placeholder(placeholder).error(R.mipmap.default_error))
                    .thumbnail(Glide.with(context).load(placeholder).apply(roundRequestOptions(mCorners)))
                    .into(imageView);
    }
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayRoundImage(Context context, String url, ImageView imageView,
                                         int mCorners, int placeholder, int width, int height) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(roundRequestOptions(mCorners).placeholder(placeholder)
                            .override(ScreenUtils.dp2px(width),ScreenUtils.dp2px(height)))
                    .thumbnail(Glide.with(context).load(placeholder).apply(roundRequestOptions(mCorners)))
                    .into(imageView);
    }

    public static void getBitmapResources(Context context, String url, LoadCallBack<Bitmap> callBack) {
        Observable.just(url).flatMap((Function<String, Observable<FutureTarget<Bitmap>>>) s -> Observable.just(Glide.with(context).asBitmap().load(s).submit())).subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).subscribe(new Observer<FutureTarget<Bitmap>>() {
            private Disposable mDisposable;
            @Override
            public void onSubscribe(Disposable d) {
                mDisposable = d;
            }

            @Override
            public void onNext(FutureTarget<Bitmap> bitmapFutureTarget) {
                try {
                    callBack.loadSuccess(bitmapFutureTarget.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onError(Throwable e) {
                callBack.loadFail();
                if (mDisposable != null && !mDisposable.isDisposed()) {
                    mDisposable.dispose();
                }
            }

            @Override
            public void onComplete() {
                if (mDisposable != null && !mDisposable.isDisposed()) {
                    mDisposable.dispose();
                }
            }
        });
    }

    public static void getNewBitmapResources(Context context, String url, LoadNewCallBack<Bitmap> callBack) {
        Observable.just(url).flatMap((Function<String, Observable<FutureTarget<Bitmap>>>) s -> Observable.just(Glide.with(context).asBitmap().load(s).submit())).subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).subscribe(new Observer<FutureTarget<Bitmap>>() {
            private Disposable mDisposable;
            @Override
            public void onSubscribe(Disposable d) {
                mDisposable = d;
                callBack.onSubscribe(mDisposable);
            }

            @Override
            public void onNext(FutureTarget<Bitmap> bitmapFutureTarget) {
                try {
                    callBack.loadSuccess(bitmapFutureTarget.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onError(Throwable e) {
                callBack.loadFail();
                if (mDisposable != null && !mDisposable.isDisposed()) {
                    mDisposable.dispose();
                }
            }

            @Override
            public void onComplete() {
                if (mDisposable != null && !mDisposable.isDisposed()) {
                    mDisposable.dispose();
                }
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayCircleImage(Context context, String url, ImageView imageView) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(new RequestOptions().bitmapTransform(new MultiTransformation(new CenterCrop(), new CircleCrop())))
                    .thumbnail(0.1f)
                    .into(imageView);
    }
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayCircleImage(Context context, String url, ImageView imageView, int placeholder) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(new RequestOptions().bitmapTransform(new MultiTransformation(new CenterCrop(), new CircleCrop()))
                            .placeholder(placeholder).error(R.mipmap.default_error))
                    .thumbnail(0.1f)
                    .into(imageView);
    }
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void displayCircleImage(Context context, String url, ImageView imageView, int placeholder, int width, int height) {
        if (checkContextIllegal(context))
            Glide.with(context)
                    .load(url)
                    .apply(new RequestOptions().bitmapTransform(new MultiTransformation(new CenterCrop(), new CircleCrop()))
                            .override(ScreenUtils.dp2px(width),ScreenUtils.dp2px(height))
                            .placeholder(placeholder).error(R.mipmap.default_error))
                    .thumbnail(0.1f)
                    .into(imageView);
    }



    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void clearMemory(Activity mContext) {
        if (mContext != null && !mContext.isFinishing()) {
            if (mContext.isDestroyed()) return;
            Glide.get(mContext).clearMemory();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void onTrimMemory(Activity mContext, int mLevel) {
        if (mContext != null && !mContext.isFinishing()) {
            if (mContext.isDestroyed()) return;
            if (mLevel == mContext.TRIM_MEMORY_UI_HIDDEN) {
                clearMemory(mContext);
            }
            Glide.get(mContext).trimMemory(mLevel);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void pauseRequests(FragmentActivity activity) {
        if (activity != null && !activity.isFinishing()) {
            if (activity.isDestroyed()) return;
            Glide.with(activity.getApplicationContext()).pauseRequests();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static void resumeRequests(FragmentActivity activity) {
        if (activity != null && !activity.isFinishing()) {
            if (activity.isDestroyed()) return;
            Glide.with(activity.getApplicationContext()).resumeRequests();
        }
    }
}
